package main

import "fmt"

func main() {
	arrayDemo()
	sliceDemo()
	mapDemo()
}

// array数组
// 数组存放的是固定长度、相同数据类型的数据，而且这些存放的元素是连续的。
func arrayDemo() {
	fmt.Println("******array数组******")
	array := [5]string{"a", "b", "c", "d", "e"}
	fmt.Println(array[2])

	//省略长度
	array2 := [...]string{"a", "b", "c", "d", "e"}
	fmt.Println(array2[2])

	//循环输出数组
	for i := 0; i < 5; i++ {
		fmt.Println("数组索引：%d，对应值：%s\n", i, array[i])
	}
	//for range方式输出数组
	fmt.Println("*******************************")
	for i, v := range array {
		fmt.Println("数组索引：%d，对应值：%s\n", i, v)
	}
}

// slice切片
// 切片和数组类似，可以把它理解为动态数组。切片是基于数组实现的，他的底层就是一个数组。
func sliceDemo() {
	fmt.Println("******slice切片******")
	//基于数组生成切片：slice:=array[start:end]
	//包含索引start，但是不包含索引end
	ints := [5]int{1, 2, 3, 4, 5}
	slice := ints[2:5]
	fmt.Println("修改前原数组：", ints)
	fmt.Println("修改前切片：", slice)
	slice[1] = 10086 //切片修改
	fmt.Println("修改后原数组：", ints)
	fmt.Println("修改后切片：", slice)

	//切片声明
	//除了可以从一个数组得到切片外，还可以声明切片，使用make函数。
	fmt.Println("******make声明切片******")
	slice2 := make([]string, 4)    //声明了一个元素类型为string的切片，长度是4.
	slice3 := make([]string, 4, 8) //声明了一个元素类型为string的切片，长度是4，容量为8.
	fmt.Println("******字面量声明切片******")

	//通过字面量的方式声明和初始化切片
	//切片和数组的字面量初始化方式，差别就是中括号[]里的长度。
	slice4 := []int{11, 22, 33, 44, 55}
	fmt.Println("切片slice2：", slice2)
	fmt.Println("切片slice3：", slice3)
	fmt.Println("切片slice4：", slice4)

	//通过内置的 append 函数对一个切片追加元素，返回新切片
	//追加一个元素
	slice5 := append(slice2, "aaaaaa")
	fmt.Println("slice5 = ", slice5)
	//追加多个元素
	slice6 := append(slice3, "aaaaaa", "bbbbb", "ccccc")
	fmt.Println("slice6 = ", slice6)
	//追加另一个切片
	slice7 := append(slice5, slice6...)
	fmt.Println("slice7 = ", slice7)
	for i, v := range slice7 {
		fmt.Println("切片索引：%d，对应值：%s\n", i, v)
	}
}

// map映射
func mapDemo() {
	fmt.Println("******map映射******")
	//map声明初始化
	//创建一个map可以通过内置的make函数。
	nameAgeMap := make(map[string]int)

	//通过字面量方式创建map
	map1 := map[string]int{"songfayuan": 30}
	fmt.Println("map1 = ", map1)

	//添加键值对或者更新对应key的value
	nameAgeMap["宋发元"] = 30
	nameAgeMap["宋发元2"] = 31
	nameAgeMap["宋发元3"] = 32
	fmt.Println("nameAgeMap = ", nameAgeMap)

	//获取指定key对应的value
	//第一个值是对应的 Value；
	//第二个值标记该 Key 是否存在，如果存在，它的值为 true。
	age, ok := nameAgeMap["宋发元"]
	if ok {
		fmt.Println(age)
	}

	//删除键值对
	delete(nameAgeMap, "宋发元")
	age2, ok2 := nameAgeMap["宋发元"]
	if ok2 {
		fmt.Println(age2)
	}

	//遍历map
	for key, value := range nameAgeMap {
		fmt.Println("key is ", key, "value is ", value)
	}

	//map的大小
	fmt.Println("map的大小：", len(nameAgeMap))
}
